#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMenuBar>
#include <QStackedWidget>
#include "Path.h"
#include "AppConfig.h"
#include "CHttpServer.h"
#include "HttpUtil.h"
#include "TStringUtil.h"


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    setupUI();

	startHttp();
}

MainWindow::~MainWindow()
{
	stopHttp();

    delete ui;
}

void MainWindow::on_actionExit_triggered()
{
    close();
}

void MainWindow::on_actionConfig_triggered()
{

}

void MainWindow::on_actionStart_triggered()
{
    if (isStarted())
    {
        stopCamera();
    }

    startCamera();
}

void MainWindow::on_actionStop_triggered()
{
    stopCamera();
}

void MainWindow::setupUI()
{
	std::string configPath = getParamsPath();
	AppConfig::setFilePath(configPath);

    Camera::listDevice(m_deviceList);

    size_t maxCount = FormCamera::MAX_COUNT;
    if (m_deviceList.size() > maxCount)
    {
        m_deviceList.resize(maxCount);
    }

    setupMenu();

    setupCameraForm();

}

void MainWindow::setupMenu()
{
    QMenu* devMenu = menuBar()->addMenu("&Camera");

    for (size_t i = 0; i < m_deviceList.size(); i ++)
    {
        std::string name = m_deviceList[i].name;

        qDebug("%s", name.c_str());

        QAction* action = new QAction(name.c_str(), this);
        action->setData(m_deviceList[i].index);

        connect(action, &QAction::triggered, this, &MainWindow::onClickCamera);

        devMenu->addAction(action);

        m_actionList.push_back(action);
    }
}

void MainWindow::onClickCamera()
{
    QObject* obj = sender();
    QAction* action = (QAction*)obj;

    int index = action->data().toInt();

    qDebug("click %d", index);

    startCamera();
}

void MainWindow::setupCameraForm()
{
	ui->widget->setCamera(m_deviceList);

	connect(ui->widget, &FormCamera::countResult, this, &MainWindow::onCountResult);
}

void MainWindow::resizeEvent(QResizeEvent *event)
{

}

std::string MainWindow::getParamsPath()
{
	std::string filepath = comn::Path::getWorkDir();
	filepath = comn::Path::join(filepath, "HeadCounter.ini");
	return filepath;
}

void MainWindow::startHttp()
{
	m_httpServer.reset(new CHttpServer());
	m_httpServer->setUserFile(NULL);

	m_httpServer->addJsonApi("/api");

	setupUri();

	int port = AppConfig::getInt("App/HttpPort", 18800);
	m_httpServer->start(port, this);
}

void MainWindow::stopHttp()
{
	m_httpServer->stop();
}

void MainWindow::broadcast(const std::string& text)
{
	m_httpServer->broadcast(const_cast<char*>(text.c_str()), text.size());
}

void MainWindow::setupUri()
{
}

int MainWindow::handleJsonApi(HttpRequest& request, std::string& json)
{
	if (HttpUtil::isOption(request.method))
	{
		return 0;
	}

	int rc = 404;
	if (mg_vcmp(&request.uri, "/api/camera") == 0)
	{
		rc = getCameraList(request, json);
	}
	
	return rc;
}

void MainWindow::handleUpload(const char* name, const std::string& filepath)
{
	//
}

int MainWindow::handleFileApi(HttpRequest& request, std::string& resp, std::string& mime)
{
	return 0;
}

void MainWindow::handleWebSocketFrame(unsigned char *data, size_t size, unsigned char flags)
{
	//
}

int MainWindow::getCameraList(HttpRequest& request, std::string& jsonText)
{
	size_t count = m_deviceList.size();
	jsonText = comn::StringUtil::format("{\"count\": %d}", count);
	return 0;
}

void MainWindow::notifyCameraStatus(int index, bool opened)
{
	std::string status = opened ? "opened" : "closed";
	std::string text = comn::StringUtil::format("{\"index\": %d,\"camera_status\": \"%s\"}", 
		index, status.c_str());
	broadcast(text);
}

void MainWindow::onCountResult(int index, int count, int status, bool exception)
{
	std::string boolStr = exception ? "true" : "false";
	std::string text = comn::StringUtil::format("{\"index\": %d,\"status\": %d,\"count\": %d,\"exception\": %s}",
		index, status, count, boolStr.c_str());

	broadcast(text);
}

void MainWindow::startCamera()
{
    ui->widget->start();
}

void MainWindow::stopCamera()
{
    ui->widget->stop();
}

bool MainWindow::isStarted()
{
    return ui->widget->isStarted();
}
